Here is a patch to enable Xen to run on a Unisys ES7000 x86_64 system.
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 21 Jul 2005 15:50:11 +0000 (15:50 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 21 Jul 2005 15:50:11 +0000 (15:50 +0000)
Signed-off-by: Aravindh Puthiyaparambil <aravindh.puthiyaparambil@unisys.com>
xen/arch/x86/genapic/es7000plat.c
xen/arch/x86/io_apic.c
xen/arch/x86/mpparse.c
xen/include/asm-x86/apicdef.h
xen/include/asm-x86/genapic.h
xen/include/asm-x86/mach-bigsmp/mach_apic.h
xen/include/asm-x86/mach-default/mach_apic.h
xen/include/asm-x86/mach-es7000/mach_apic.h
xen/include/asm-x86/mach-generic/mach_apic.h
xen/include/asm-x86/mach-summit/mach_apic.h

index 8bf571bd273ea97a9744635c6c1117a37e816c7d..1f7150f9f9b113695cd7e0525aa5cb33f4a82360 100644 (file)
@@ -136,7 +136,19 @@ parse_unisys_oem (char *oemptr, int oem_entries)
                es7000_plat = 0;
        } else {
                printk("\nEnabling ES7000 specific features...\n");
-               es7000_plat = 1;
+               /*
+                * Determine the generation of the ES7000 currently running.
+                *
+                * es7000_plat = 0 if the machine is NOT a Unisys ES7000 box
+                * es7000_plat = 1 if the machine is a 5xx ES7000 box
+                * es7000_plat = 2 if the machine is a x86_64 ES7000 box
+                *
+                */
+               if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2))
+                       es7000_plat = 2;
+               else
+                       es7000_plat = 1;
+
                ioapic_renumber_irq = es7000_rename_gsi;
        }
        return es7000_plat;
@@ -286,7 +298,7 @@ es7000_stop_cpu(int cpu)
 void __init
 es7000_sw_apic()
 {
-       if (es7000_plat) {
+       if (es7000_plat == 1) {
                int mip_status;
                struct mip_reg es7000_mip_reg;
 
index 255b5907580d2ba9414e4f28b97b8d6ef1526ea6..db3cd010a8b4258111f827f282159bbee329180e 100644 (file)
@@ -955,6 +955,13 @@ static void __init setup_ioapic_ids_from_mpc(void)
     unsigned char old_id;
     unsigned long flags;
 
+    /*
+     * Don't check I/O APIC IDs for xAPIC systems. They have
+     * no meaning without the serial APIC bus.
+     */
+    if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && boot_cpu_data.x86 < 15))
+        return;
+
     /*
      * This is broken; anything with a real cpu count has to
      * circumvent this idiocy regardless.
@@ -981,10 +988,6 @@ static void __init setup_ioapic_ids_from_mpc(void)
             mp_ioapics[apic].mpc_apicid = reg_00.bits.ID;
         }
 
-        /* Don't check I/O APIC IDs for some xAPIC systems.  They have
-         * no meaning without the serial APIC bus. */
-        if (NO_IOAPIC_CHECK)
-            continue;
         /*
          * Sanity check, is the ID really free? Every APIC in a
          * system must have a unique ID or we get lots of nice
index 234b14106f527a1007882671d617154291d3c971..268c9cdf71db08910f529eebb50052b4e04e3fca 100644 (file)
@@ -913,7 +913,10 @@ void __init mp_register_ioapic (
        mp_ioapics[idx].mpc_apicaddr = address;
 
        set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
-       mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id);
+       if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 < 15))
+               mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id);
+       else
+               mp_ioapics[idx].mpc_apicid = id;
        mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx);
        
        /* 
@@ -995,9 +998,9 @@ void __init mp_config_acpi_legacy_irqs (void)
        Dprintk("Bus #%d is ISA\n", MP_ISA_BUS);
 
        /*
-        * ES7000 has no legacy identity mappings
+        * Older generations of ES7000 have no legacy identity mappings
         */
-       if (es7000_plat)
+       if (es7000_plat == 1)
                return;
 
        /* 
@@ -1053,11 +1056,20 @@ void __init mp_config_acpi_legacy_irqs (void)
        }
 }
 
+#define MAX_GSI_NUM    4096
+
 int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
 {
        int                     ioapic = -1;
        int                     ioapic_pin = 0;
        int                     idx, bit = 0;
+       static int              pci_irq = 16;
+       /*
+        * Mapping between Global System Interrups, which
+        * represent all possible interrupts, and IRQs
+        * assigned to actual devices.
+        */
+       static int              gsi_to_irq[MAX_GSI_NUM];
 
 #ifdef CONFIG_ACPI_BUS
        /* Don't set up the ACPI SCI because it's already set up */
@@ -1092,11 +1104,26 @@ int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
        if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
                Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
                        mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
-               return gsi;
+               return gsi_to_irq[gsi];
        }
 
        mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
 
+       if (edge_level) {
+               /*
+                * For PCI devices assign IRQs in order, avoiding gaps
+                * due to unused I/O APIC pins.
+                */
+               int irq = gsi;
+               if (gsi < MAX_GSI_NUM) {
+                       gsi = pci_irq++;
+                       gsi_to_irq[irq] = gsi;
+               } else {
+                       printk(KERN_ERR "GSI %u is too high\n", gsi);
+                       return gsi;
+               }
+       }
+
        io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
                    edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
                    active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);
index 911a55ef82f75417cea4e401ef206bfb4885673d..5357707cede84c46234698dbe17d3175b91cc7d7 100644 (file)
 
 #define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
 
-#ifdef CONFIG_NUMA
- #define MAX_IO_APICS 32
+/* These limits are dictated by ES7000 hardware. */
+#ifdef __i386__
+ #define MAX_IO_APICS 65
 #else
- #define MAX_IO_APICS 8
+ #define MAX_IO_APICS 129
 #endif
 
 /*
index fc813b2e82740f996e7dea8ceabb449f442e5d50..3e9f9270c19d6f1e4ad068d8bf9b1c92c7f5438e 100644 (file)
@@ -30,7 +30,6 @@ struct genapic {
        unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid);
        unsigned long (*check_apicid_present)(int apicid); 
        int no_balance_irq;
-       int no_ioapic_check;
        void (*init_apic_ldr)(void);
        physid_mask_t (*ioapic_phys_id_map)(physid_mask_t map);
 
@@ -78,7 +77,6 @@ struct genapic {
        .int_delivery_mode = INT_DELIVERY_MODE, \
        .int_dest_mode = INT_DEST_MODE, \
        .no_balance_irq = NO_BALANCE_IRQ, \
-       .no_ioapic_check = NO_IOAPIC_CHECK, \
        .ESR_DISABLE = esr_disable, \
        .apic_destination_logical = APIC_DEST_LOGICAL, \
        APICFUNC(apic_id_registered), \
index 1540c1f9343e523eef91f288ed6ead5ebbce7416..fe7d4fcec03bd4bfcaed930f80e1c7a165a6d931 100644 (file)
@@ -14,8 +14,6 @@
 #define NO_BALANCE_IRQ (1)
 #define esr_disable (1)
 
-#define NO_IOAPIC_CHECK (0)
-
 static inline int apic_id_registered(void)
 {
        return (1);
index 4bf3c5ae341890959b05ad7f2b832bc33a03c022..922c2fa57acabf18b23c9c20e994998b4b2dacbf 100644 (file)
@@ -19,8 +19,6 @@ static inline cpumask_t target_cpus(void)
 #define NO_BALANCE_IRQ (0)
 #define esr_disable (0)
 
-#define NO_IOAPIC_CHECK (0)
-
 #define INT_DELIVERY_MODE dest_LowestPrio
 #define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
 
index 4cf0e75a6d41aefe081de449b153094cf5fdbc86..1d89ed2de53d709faaa28a888213bfa409f8bf91 100644 (file)
@@ -38,8 +38,6 @@ static inline cpumask_t target_cpus(void)
 #define WAKE_SECONDARY_VIA_INIT
 #endif
 
-#define NO_IOAPIC_CHECK (1)
-
 static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
 { 
        return 0;
index ab36d02ebedecc9d7c17a991e9913ce4f5f8046c..b13767a4e9345211eaa68a5c1439ee59f82e6cdc 100644 (file)
@@ -5,7 +5,6 @@
 
 #define esr_disable (genapic->ESR_DISABLE)
 #define NO_BALANCE_IRQ (genapic->no_balance_irq)
-#define NO_IOAPIC_CHECK        (genapic->no_ioapic_check)
 #define INT_DELIVERY_MODE (genapic->int_delivery_mode)
 #define INT_DEST_MODE (genapic->int_dest_mode)
 #undef APIC_DEST_LOGICAL
index 61cac6b453f015022158e94cf6da259d25abad0f..c43074a7aeae4f2573fb9be1dae67f361b7529ff 100644 (file)
@@ -7,8 +7,6 @@
 #define esr_disable (1)
 #define NO_BALANCE_IRQ (0)
 
-#define NO_IOAPIC_CHECK (1)    /* Don't check I/O APIC ID for xAPIC */
-
 /* In clustered mode, the high nibble of APIC ID is a cluster number.
  * The low nibble is a 4-bit bitmap. */
 #define XAPIC_DEST_CPUS_SHIFT  4